#include "s-int.h"



BOOL GetProcessMD5(HANDLE hProcess, unsigned char degist[16], int nSize)
{
	WCHAR lpszFileName[MAX_CHAR];
	if(!Process::GetProcessFileName(hProcess, lpszFileName, MAX_CHAR))
		return FALSE;

	return GetFileMD5(lpszFileName, MAX_CHAR, degist, nSize);
}

BOOL GetFileMD5(LPCWSTR lpszFileName, int nFileSize, unsigned char degist[16], int nSize)
{
	WriteLogger("Get MD5 from %s", lpszFileName);


	//GetFileSizeEx
	WIN32_FILE_ATTRIBUTE_DATA fi;
	if(!GetFileAttributesExW(lpszFileName, GetFileExInfoStandard, &fi))
		return FALSE;

	WriteLogger("Length - low: %d, high: %d", fi.nFileSizeLow, fi.nFileSizeHigh);


	HANDLE hFile = File::Open(lpszFileName);
	if(!hFile)
		return FALSE;

	DWORD dwRead;
	char* pBuffer = (char*)Marshal::AllocCoTaskMem(fi.nFileSizeLow);
	if(!ReadFile(hFile, pBuffer, fi.nFileSizeLow, &dwRead, NULL))
	{
		Marshal::FreeCoTaskMem(pBuffer);
		return FALSE;
	}

	MD5::MD5CryptoServiceProvider(degist, (unsigned const char*)pBuffer, fi.nFileSizeLow);
	Marshal::FreeCoTaskMem(pBuffer);

	WriteLogger("MD5=%s", degist);


	return TRUE;
}

int AntiFPERoutine(void)
{
	WriteLogger("Anti FPE engine launched");

	stdext::hash_set<std::wstring> fpe;

	fpe.insert(L"KnightV.exe");
	fpe.insert(L"Cheat Engine.exe");
	fpe.insert(L"netmon.exe");
	

	typedef NTSTATUS
		(NTAPI*
		NtQuerySystemInformationPrototype) (
		IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
		OUT PVOID SystemInformation,
		IN ULONG SystemInformationLength,
		OUT PULONG ReturnLength OPTIONAL
		);
	NtQuerySystemInformationPrototype pNtQuerySystemInformation = (NtQuerySystemInformationPrototype)
		GetProcAddress(LoadLibraryW(L"ntdll"), "NtQuerySystemInformation");

		

	ULONG uOutLen = 0;
	PVOID pData = NULL;
	PSYSTEM_PROCESS_INFORMATION pspi;

	while(TRUE)
	{
		Sleep(15000);

		// get system process info
		pNtQuerySystemInformation(
			SystemProcessInformation,
			pData,
			0,
			&uOutLen);
		pData = Marshal::AllocCoTaskMem(uOutLen);
		pNtQuerySystemInformation(
			SystemProcessInformation,
			pData,
			uOutLen,
			NULL);
		
		// detect FPE processes
		pspi = (PSYSTEM_PROCESS_INFORMATION)pData;


		do
		{
			//
			std::wstring s((wchar_t*)(pspi->Reserved2[1]), *(unsigned short*)(pspi->Reserved2));
			if(fpe.find(s.c_str()) != fpe.end())
			{
				AceSuicide();
			}

			//
			pspi = (PSYSTEM_PROCESS_INFORMATION)
				(((BYTE *)pspi)+ pspi->NextEntryOffset);
		}while(pspi->NextEntryOffset);

    	Marshal::FreeCoTaskMem(pData);
	}


	return 0;
}
